import json
from xmlrpc.client import boolean
from docx import Document
from docx.shared import Pt
import requests
import os

def load_swagger_json(url_or_path):
    # 根据URL或本地路径加载Swagger JSON数据
    if url_or_path.startswith('http'):
        # 如果是URL，则使用requests获取
        response = requests.get(url_or_path)
        response.raise_for_status()  # 检查请求是否成功
        return response.json()
    else:
        # 如果是本地文件路径，则直接打开文件
        with open(url_or_path, 'r', encoding='utf-8') as file:
            return json.load(file)

def add_parameter_table(document, parameters, parent_name=""):
    # 添加参数表格，支持嵌套对象
    if not parameters:
        return

    table = document.add_table(rows=1, cols=4)
    table.style = 'Table Grid'  # 使用内置的表格风格
    hdr_cells = table.rows[0].cells
    hdr_cells[0].text = '参数名称'
    hdr_cells[1].text = '参数说明'
    hdr_cells[2].text = '请求类型'
    hdr_cells[3].text = '是否必须'

def get_definitions(swagger_data, ref):
    # 根据$ref解析并返回定义的对象
    ref_path = ref.split('/')[-1]
    return swagger_data['definitions'][ref_path]


def add_dict_parameters(table, properties, swagger_data, parent_name=''):
    for key, value in properties.items():
        name = f"   {key}" if parent_name else key
        description = value.get('description', '')
        param_type = value.get('type', '')
        required = str(not value.get('allowEmptyValue', boolean))

        # 添加普通参数
        row_cells = table.add_row().cells
        row_cells[0].text = name
        row_cells[1].text = description
        row_cells[2].text = param_type
        row_cells[3].text = required
        # 下面是处理对象里面有对象的情况，但是容易造成递归超过限制
        # if '$ref' in value:
        #     # 处理引用的定义
        #     definition = get_definitions(swagger_data, value['$ref'])
        #     properties = definition.get('properties', [])
        #     if isinstance(properties, list):
        #         add_list_parameters(table, properties, swagger_data, name)
        #     elif isinstance(properties, dict):
        #         add_dict_parameters(table, properties, swagger_data, name)
        # elif 'items' in value and '$ref' in value['items']:
        #     # 处理数组中的引用定义
        #     definition = get_definitions(swagger_data, value['items']['$ref'])
        #     properties = definition.get('properties', [])
        #     if isinstance(properties, list):
        #         add_list_parameters(table, properties, swagger_data, name)
        #     elif isinstance(properties, dict):
        #         add_dict_parameters(table, properties, swagger_data, name)




def add_list_parameters(table, parameters, swagger_data, parent_name=''):
    """递归添加复杂参数到表格"""
    for param in parameters:
        name = f"   {param}" if parent_name else param['name']
        description = param.get('description', '')
        param_type = param.get('type', '')
        required = str(param.get('required', ''))

        row_cells = table.add_row().cells
        row_cells[0].text = name
        row_cells[1].text = description
        row_cells[2].text = param_type
        row_cells[3].text = required

        if 'schema' in param and '$ref' in param['schema']:
            # 处理引用的定义
            definition = get_definitions(swagger_data, param['schema']['$ref'])
            properties = definition.get('properties', [])
            if isinstance(properties, list):
                add_list_parameters(table, properties, swagger_data, name)
            elif isinstance(properties, dict):
                add_dict_parameters(table, properties, swagger_data, name)
        elif 'items' in param and '$ref' in param['items']:
            # 处理数组中的引用定义
            definition = get_definitions(swagger_data, param['items']['$ref'])
            properties = definition.get('properties', [])
            add_list_parameters(table, properties, swagger_data, name + '[]')
            if isinstance(properties, list):
                add_list_parameters(table, properties, swagger_data, name)
            elif isinstance(properties, dict):
                add_dict_parameters(table, properties, swagger_data, name)


def swagger_to_word(swagger_data, output_path):
    document = Document()

    # 添加标题
    title_style = document.styles['Title']
    title_style.font.size = Pt(16)  # 设置标题字体大小
    document.add_heading(swagger_data["info"]["title"], level=1).style = title_style

    summary_style = document.styles['Normal']
    summary_style.paragraph_format.space_before = Pt(5)  # 设置段落前空格
    summary_style.paragraph_format.space_after = Pt(5)  # 设置段落后空格

    # 遍历paths对象，添加每个API路径的信息
    for path, methods in swagger_data['paths'].items():
        for method, details in methods.items():
            heading_style = document.styles['Heading 1']
            heading_style.font.size = Pt(14)  # 设置一级标题字体大小
            document.add_heading(details.get('summary', ''), level=1).style = heading_style
            document.add_paragraph(f"接口地址：{path}", style=summary_style)
            document.add_paragraph(f"请求方式：{method.upper()}", style=summary_style)
            document.add_paragraph(f"请求数据类型：{details.get('consumes', '')}", style=summary_style)
            document.add_paragraph(f"响应数据类型：{details.get('produces', '')}", style=summary_style)

            parameters = details.get('parameters', [])
            document.add_paragraph("请求参数：")
            if parameters:
                table = document.add_table(rows=1, cols=4)
                table.style = 'Table Grid'  # 使用内置的表格风格
                hdr_cells = table.rows[0].cells
                hdr_cells[0].text = '参数名称'
                hdr_cells[1].text = '参数说明'
                hdr_cells[2].text = '请求类型'
                hdr_cells[3].text = '是否必须'

                add_list_parameters(table, parameters, swagger_data)
            else:
                document.add_paragraph("无")

            # 添加响应信息
            responses = details.get('responses', {})
            if responses:
                document.add_paragraph("响应状态：")
                table = document.add_table(rows=1, cols=4)
                table.style = 'Table Grid'  # 使用内置的表格风格
                hdr_cells = table.rows[0].cells
                hdr_cells[0].text = '状态码'
                hdr_cells[1].text = '说明'

                for status_code, response in responses.items():
                    row_cells = table.add_row().cells
                    row_cells[0].text = status_code
                    row_cells[1].text = response.get('description', '')

                document.add_paragraph("响应参数：")
                result = responses["200"]
                if 'schema' in result and '$ref' in result['schema']:
                    table = document.add_table(rows=1, cols=4)
                    table.style = 'Table Grid'  # 使用内置的表格风格
                    hdr_cells = table.rows[0].cells
                    hdr_cells[0].text = '参数名称'
                    hdr_cells[1].text = '参数说明'
                    hdr_cells[2].text = '类型'

                    add_list_parameters(table, parameters, swagger_data)
                else:
                    document.add_paragraph("无")


    # 保存文档
    document.save(output_path)

def swagger2word(swagger_url_or_path):
    # 输出Word文档的路径
    output_word_path = 'swagger接口文档'
    base_name = output_word_path
    extension = '.docx'

    i = 1
    while os.path.exists(f"{output_word_path}{extension}"):
        output_word_path = f"{base_name}({i})"
        i += 1

    output_word_path += extension



    # 加载Swagger JSON
    swagger_data = load_swagger_json(swagger_url_or_path)
    # 将Swagger JSON转换为Word文档
    swagger_to_word(swagger_data, output_word_path)

    return output_word_path